package server.model.connections;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;

import server.model.dao.FilesDAO;
import server.model.dao.UsersDAO;
import server.model.dbms.SQLInstanceManager;

import model.dto.FileDTO;
import model.dto.NetPackage;
import model.dto.UserDTO;
import model.enums.RequestType;
import model.enums.ResponseType;
import model.xml.XMLCodec;


public class RequestManager {

	@SuppressWarnings("unchecked")
	public void processRequest(String strReq, OutputStream ous) throws FileNotFoundException{
		//inputstream trash validation
		if(!strReq.startsWith("<")){
			System.out.println("Check inputstream trash! - Received: " + strReq);
			return;
		}

		NetPackage request=null;
		Map<String, Class>aliases=new HashMap<String, Class>();
		//Loading aliases starts
		//aliases.put("request", NetPackage.class.getClass());

		//Loading aliases ends

		//attemp to parse XML String into DTO
		try{
			request=(NetPackage) XMLCodec.parseXml(aliases, strReq);
		}catch(ClassCastException e){
			System.out.println("invalid request received");
			e.printStackTrace(System.err);
		}

		NetPackage response=new NetPackage(ResponseType.valueOf(request.getType().toString()), null, null);
		System.out.println("Processing..." + request.getType().toString());

		if(request.getType().equals(RequestType.USERS_FOR_FILE)){
			//envio de un FileDTO con datos correspondientes al request(solo filtra archivo por id, completar id en fileDTO!!)
			FileDTO fileReceived=(FileDTO)request.getContent();
			response.setHeader(fileReceived);
			response.setContent(FilesDAO.getUsersForFilteredFile(SQLInstanceManager.getConnection(), fileReceived.getId(), "", "", 0));
		}else if(request.getType().equals(RequestType.FILTERED_FILES)){
			//envio de un FileDTO con datos correspondientes al request
			//0 no afecta los ids(el dao no aplica filtro)
			//si se envia ID se filtra unicamente por id, sino, filtra por otros campos ( campo LIKE %valor% ) (poner id 0 para este tipo de filtro)
			//FileDTO params: Integer id, Integer id_user, String filename, String extension, long size)
			FileDTO fileReceived=(FileDTO)request.getContent();
			response.setHeader(fileReceived);
			response.setContent(FilesDAO.getFilteredFiles(SQLInstanceManager.getConnection(), fileReceived.getId(), fileReceived.getFilename(), fileReceived.getExtension()));
		}else if(request.getType().equals(RequestType.FILES_FOR_USER)){
			//envio de un UserDTO con datos correspondientes al request (solo parametro id, los demas null)
			UserDTO userReceived=(UserDTO)request.getContent();
			response.setHeader(userReceived);
			response.setContent(null);
			FilesDAO.getUsersForFilteredFile(SQLInstanceManager.getConnection(), 0, "", "", userReceived.getId());
		}else if(request.getType().equals(RequestType.ONLINE_USERS)){
			response.setHeader(null);
			response.setContent(UsersDAO.getOnlineUsers(SQLInstanceManager.getConnection()));
		}else if(request.getType().equals(RequestType.ALL_USERS)){
			response.setHeader(null);
			response.setContent(UsersDAO.getAll(SQLInstanceManager.getConnection()));
		}else if(request.getType().equals(RequestType.CHANGE_STATUS)){
			//envio de UserDTO con id correspondiente del usuario a modificar y nuevo status(ip null)
			UserDTO userReceived=(UserDTO)request.getContent();
			response.setHeader(userReceived);
			if(UsersDAO.updateStatus(SQLInstanceManager.getConnection(), userReceived.getId(), userReceived.getStatus().toString())){
				response.setContent(ResponseType.OK);
			}else{
				response.setContent(ResponseType.ERROR);
			}
		}

		//Sent loaded response.
		try {
			XMLCodec.toXML(new HashMap<String, Class>(), response, ous);
		} catch (IOException e) {
			e.printStackTrace(System.err);
		}
	}
}
